﻿using CSRedis;
//using DataCenterApiNet;
using Himp.TaskScheduling.Hangfire;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.Extensions.Options;

namespace Himp.TaskScheduling
{
    public class RedisToDataCenterWorker : IHostedService, IDisposable
    {
        private CSRedisClient _client;
        private Timer _timer;
        private readonly TimeSpan _interval = TimeSpan.FromMilliseconds(50);
        private readonly TimeSpan _delay = TimeSpan.FromMilliseconds(0);
        private bool _isExecuting = false;
        Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
        private static readonly object _lock = new object();
        private bool _init = false;
        private ILogger<RedisToMqttWorker> _logger;
        private readonly ConnectionStringOption _connectionStrings;
        private uint dataCenterKey = 0;

        public RedisToDataCenterWorker(ILogger<RedisToMqttWorker> logger
            , IOptions<ConnectionStringOption> connectionStrings)
        {
            _connectionStrings = connectionStrings.Value;
            _logger = logger;
            // 初始化计时器，初始时不启动，等待 StartAsync 启动
            _timer = new Timer(ExecuteJob, null, _delay, Timeout.InfiniteTimeSpan);
            _client = new CSRedis.CSRedisClient(_connectionStrings.KaiYRedis);
            Console.WriteLine($"系统时间：{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
            Console.WriteLine($"设备状态连接：{_connectionStrings.KaiYRedis}");
            RedisHelper.Initialization(_client);

            int ret = 0;
            //ApiEntry.InitKey(ref dataCenterKey, cacheEnable: false, cacheFolder: "", maxCacheSizeInMB: 0);
            //ret = ApiEntry.ConnectToServer(dataCenterKey, serverIP: "192.168.193.2", serverPort: 10010);
            //ret = ApiEntry.Login(dataCenterKey, account: "Admin", password: "Admin");

            _init = true;
        }

        public static int DateTimeToUTC(DateTime dt)
        {
            DateTime value = DateTime.Parse("1970-1-1 00:00:00");
            return (int)dt.ToUniversalTime().Subtract(value).TotalSeconds;
        }

        private async void ExecuteJob(object state)
        {
            if (_isExecuting || !_init)
            {
                // 如果任务正在执行，则跳过
                return;
            }

            lock (_lock)
            {
                if (_isExecuting)
                {
                    return;
                }
                _isExecuting = true;
            }

            try
            {
                // 你的任务逻辑
                await RunAsync();

            }
            catch (Exception e)
            {
                await Console.Out.WriteLineAsync(e.Message);
            }
            finally
            {
                GC.Collect(0);
                lock (_lock)
                {
                    _isExecuting = false;
                }
                // 任务完成后重新设置计时器
                _timer.Change(_interval, Timeout.InfiniteTimeSpan);
            }
        }

        private async Task RunAsync()
        {
            var keys = RedisHelper.Keys("*");

            var tasks = keys.Where(k => !k.EndsWith(":Point") && !k.EndsWith(":Stamp")).Select(async key =>
            {
                //await Console.Out.WriteLineAsync($"获取redis点数：{keys.Count()}");
                var keySplit = key.Split(':');

                if (keySplit.Length == 4 && (keySplit[0] == "SPT1" || keySplit[0] == "RILS" || keySplit[0] == "APS1" || keySplit[0] == "MAT1" || keySplit[0] == "ASS1" || keySplit[0] == "ASS2"))
                {
                    var sVal = await RedisHelper.GetAsync(key);
                    bool dFalg = false;
                    double dVal = 0;
                    dFalg = double.TryParse(sVal, out dVal);
                    var tagName = $"{keySplit[0]}.{keySplit[1]}.{keySplit[2]}:Value"; //测点名称，格式为:实例名称+.+属性名称

                    if (dFalg)
                    {
                        //var recs = new ApiEntry.HISTORY_VALUE[]
                        //{
                        //    new ApiEntry.HISTORY_VALUE()
                        //    {
                        //        dValue = dVal,
                        //        tTime =  DateTimeToUTC(DateTime.Now),
                        //        status = 3
                        //    }
                        //};
                        ////历史结构体数组，存储需要写入的测点值HISTORY_VALUE[]? recsvar
                        //var ret = ApiEntry.WriteSinglePoint(dataCenterKey, name: tagName, recs, nCount: recs.Length);
                        //await Console.Out.WriteLineAsync($"写入点位{tagName}：{ret}:{DateTimeToUTC(DateTime.Now)}");
                    }
                    else
                    {
                        //var recs = new ApiEntry.HISTORY_STRING_VALUE[]
                        //{
                        //    new ApiEntry.HISTORY_STRING_VALUE()
                        //    {
                        //        sVal = sVal,
                        //        tTime =  DateTimeToUTC(DateTime.Now),
                        //        status = 3
                        //    }
                        //};
                        ////历史结构体数组，存储需要写入的测点值HISTORY_VALUE[]? recsvar
                        //var ret = ApiEntry.WriteSingleStringPoint(dataCenterKey, name: tagName, recs, nCount: recs.Length);
                    }
                }
            });

            await Task.WhenAll(tasks);
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer.Change(_delay, _interval);
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _timer?.Dispose();
            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }
}